#include "PlaneMgr.h"
#include "CPlane.h"
#include "Character/CreatureMgr.h"
#include "Character/npc/Npc.h"
#include "Effect/EffectMgr.h"
#include "Common/Event/Event.h"
#include "Character/MissionPart.h"
CPlaneMgr::CPlaneMgr()
{

}
CPlaneMgr::~CPlaneMgr()
{

}

bool CPlaneMgr::Init()
{
	m_i64PlaneNum = 0;
	m_mapMgr.clear();
	m_planePool = new ObjectPool<CPlane>(200, false);


	IMessageDispatch *pMessageDispatch = g_GetLogicService()->GetServiceMessageDispatch();
	if (nullptr == pMessageDispatch)
	{
		return false;
	}

	pMessageDispatch->registerClientHandler(EMODULE_ID_PLANE, this);
	//pMessageDispatch->registerClientHandler(EMODULE_ID_PLANE, this);


	return true;
}
bool CPlaneMgr::UnInit()
{

	IMessageDispatch *pMessageDispatch = g_GetLogicService()->GetServiceMessageDispatch();
	if (nullptr == pMessageDispatch)
	{
		return false;
	}

	pMessageDispatch->unregisterClientHandler(EMODULE_ID_PLANE);
	//pMessageDispatch->unregisterClientHandler(EMODULE_ID_PLANE);

	std::map<uint64_t, CPlane*>::iterator iter = m_mapMgr.begin();
	for (; iter != m_mapMgr.end(); ++iter)
	{
		m_planePool->FreeObj(iter->second);
	}
	m_mapMgr.clear();
	MMO_DELETE(m_planePool);
	return true;
}

//CharIDType cid 创建位面的玩家ID
//std::vector<uint32_t> & vConfigID  需要在位面中可见的NPC
uint64_t CPlaneMgr::CreatePlane(CharIDType cid, std::vector<uint32_t> & vNpcConfigID, std::vector<uint32_t> * pEffectID, uint32_t planeConfigID,bool isTeamFlag)
{
	
	Player * pPlayer = g_GetCreatureMgr()->GetPlayer(cid);
	if (!pPlayer)
	{
		return 0;
	}

	//战斗状态不能创建位面
	//if (pPlayer->IsFightState())
	//{
	//	LogWarningFmtPrint("fighting state can not create plane!");
	//	return 0;
	//}
	uint32_t teamID = 0;
	CPlane * pPlane = m_planePool->MallocObj();
	if (pPlane)
	{
		if (isTeamFlag)
		{
			teamID = pPlayer->GetPAttrValue(P_TEAM_ID);
		}
		if (pPlane->Init(cid, ++m_i64PlaneNum, pPlayer->GetSceneId(), teamID))
		{
			
			pPlayer->SetPlaneID(m_i64PlaneNum);
			
			m_mapMgr[m_i64PlaneNum] = pPlane;
			AddCreature(m_i64PlaneNum, vNpcConfigID);
			//AddCreature(m_i64PlaneNum, cid);

			if (planeConfigID > 0)
			{
				pPlane->SetPlaneConfigID(planeConfigID);
			}


			pPlayer->UpdateSeeLst();

			//发送消息
			OpenPlaneRsp rsp;
			rsp.set_retcode(RET_SUCCESS);
			rsp.set_planeid(planeConfigID);
			g_GetLogicService()->SendDataToClient(cid, EMODULE_ID_SCENE, LOGIC_TO_CLIENT_PLANE_OPEN_RESUTL, &rsp);


			//if (pEffectID)
			//{
			//	for (int i = 0; i < (int)pEffectID->size();++i)
			//	{
			//		g_GetEffectMgr()->OnEffect(pPlayer,pEffectID->at(i));
			//	}
			//}




			//抛出事件
			PlaneOpenEvent openPlaneEvent;
			openPlaneEvent.createCid = cid;
			openPlaneEvent.planeConfigID = planeConfigID;
			openPlaneEvent.planeID = m_i64PlaneNum;
			g_GetEvent()->FireExecute(EVENT_PLANE_OPEN, cid, CREATURE_PLAYER, (PlaneOpenEvent*)&openPlaneEvent, sizeof(PlaneOpenEvent));

			return m_i64PlaneNum;
		}
	}
	return 0;
}

bool CPlaneMgr::IsCanCreatePlane(const PlanePlaneCfgInfo& cfgInfo, Creature * pCreature)
{

	//如果不在位面所需要的场景，则直接不让创建位面
	//if (cfgInfo.mapid>0 && (uint32_t)cfgInfo.mapid != pCreature->GetMapId())
	//{
	//	LogDebugFmtPrint("create plane is not in plane mapid");
	//	return false;
	//}

	Player * pPlayer = dynamic_cast<Player*>(pCreature);
	if (pPlayer)
	{

		//杀戮之子状态不能创建位面
		if (pPlayer->InSonOfKillingStatus())
		{
			//ret = RET_ACTIVITY_SONOFKILLING_TRANS_ERROR;
			return false;
		}

		//神之遗骸状态不能创建位面
		if (pPlayer->InWorldBossStatus())
		{
			//ret = RET_ACTIVITY_WORLD_BOSS_TRANS_ERROR;
			return false;
		}
	}
	
	//各自模块根据类型验证。todo..
	uint32_t planeType = cfgInfo.type;
	switch (planeType)
	{
	case enPlaneType_Task:
	{
		MissionPart* pMissionPart = dynamic_cast<MissionPart*>(pCreature->GetPart(PART_MISSION));
		if (pMissionPart)
		{
			
			//没有配任务 ，作测试用
			if (cfgInfo.param.length()<=0)
			{
				return true;
			}

			std::vector<int> vStr;
			StringSplit2Int(cfgInfo.param, ',', vStr);
			for (int i = 0; i < (int)vStr.size(); ++i)
			{
				if (pMissionPart->HaveAccpet(vStr[i]))
				{
					return true;
				}
			}
			
		}
		LogDebugFmtPrint("not have this task ,can not create plane ");
		return false;
	}
	default:
		break;
	}
	return true;
}

uint64_t CPlaneMgr::CreatePlane(CharIDType cid, int32_t planeConfigID,bool isTeamFlag)
{
	Player * pPlayer = g_GetCreatureMgr()->GetPlayer(cid);
	if (!pPlayer)
	{
		return 0;
	}


	uint64_t planeID = pPlayer->GetPlaneID();
	//如果有位面存在，则先销毁之前的位面数据，再创建后面的 
	if (planeID>0)  //个人觉得没必要用这个，任务有需求，只清空数据，不通知客户端
	{
		//如果有相同的位面配置，说明是从同一个位面，不用处理
		CPlane *pPlane = GetPlane(planeID);
		if (pPlane && pPlane->GetPlaneConfigID()>0 && pPlane->GetPlaneConfigID()==(uint32_t)planeConfigID)
		{
			return planeID;
		}
		//不相同，则先清空
		DestroyPlane(cid, planeID, false);
	}

	const PlanePlaneCfgInfo * pConfig=g_GetPlanePlaneCfgTable()->GetPlanePlaneCfgInfo(planeConfigID);
	if (!pConfig)
	{
		LogDebugFmtPrint("CPlaneMgr::CreatePlane planeConfigid=%d is not exist", planeConfigID);
		return 0;
	}
	if (!IsCanCreatePlane(*pConfig, pPlayer))
	{
		LogDebugFmtPrint("cid=%lld can not create plane planconfigid=%d", cid, planeConfigID);
		return 0;
	}

	std::vector<uint32_t> vConfigNpc;
	std::vector<uint32_t> vEffect;
	for (int i = 0; i < (int)pConfig->vec_npcid.size();++i)
	{
		vConfigNpc.push_back(pConfig->vec_npcid[i]);
	}

	for (int i = 0; i < (int)pConfig->vec_effectid.size();++i)
	{
		vEffect.push_back(pConfig->vec_effectid[i]);
	}

	return CreatePlane(cid, vConfigNpc, &vEffect, planeConfigID,isTeamFlag);
}

void CPlaneMgr::DestroyPlane(CharIDType cid, int32_t planID, bool bNoticeFlag)
{
	Creature * pCreature = g_GetCreatureMgr()->GetCreature(cid);
	if (pCreature)
	{
		pCreature->SetPlaneID(0);
		std::map<uint64_t, CPlane*>::iterator iter = m_mapMgr.find(planID);
		if (iter !=m_mapMgr.end() )
		{
			if (!iter->second)
				return;

			if (bNoticeFlag)
			{
				pCreature->UpdateSeeLst();  //即时更新一次视野
			
				//抛出事件
				PlaneCloseEvent closePlaneEvent;
				closePlaneEvent.createCid = cid;
				closePlaneEvent.planeConfigID = iter->second->GetPlaneConfigID();
				closePlaneEvent.planeID = planID;
				g_GetEvent()->FireExecute(EVENT_PLANE_CLOSE, cid, CREATURE_PLAYER, (PlaneCloseEvent*)&closePlaneEvent, sizeof(PlaneCloseEvent));
			}
			iter->second->UnInit();
			m_planePool->FreeObj(iter->second);
			m_mapMgr.erase(iter);
		}
	}
}


void CPlaneMgr::DestroyPlaneByPlaneID(uint64_t planeID)
{
	std::map<uint64_t, CPlane*>::iterator iter = m_mapMgr.find(planeID);
	if (iter != m_mapMgr.end())
	{

		//抛出事件
		PlaneCloseEvent closePlaneEvent;
		closePlaneEvent.createCid = iter->second->GetCreaterID();
		closePlaneEvent.planeConfigID = iter->second->GetPlaneConfigID();
		closePlaneEvent.planeID = planeID;
		g_GetEvent()->FireExecute(EVENT_PLANE_CLOSE, iter->second->GetCreaterID(), CREATURE_PLAYER, (PlaneCloseEvent*)&closePlaneEvent, sizeof(PlaneCloseEvent));


		m_mapMgr.erase(iter);

		iter->second->UnInit();
		m_planePool->FreeObj(iter->second);
	}
	
}
std::vector<uint64_t>  CPlaneMgr::GetPlaneNoPlayerList(uint64_t planeID)
{
	std::map<uint64_t, CPlane*>::iterator iter = m_mapMgr.find(planeID);
	if (iter != m_mapMgr.end())
	{
		return iter->second->GetNoPlayerList();
	}
	return std::vector<uint64_t>();
}

std::vector<uint64_t> CPlaneMgr::GetPlanePlayerList(uint64_t planeID)
{
	std::map<uint64_t, CPlane*>::iterator iter = m_mapMgr.find(planeID);
	if (iter != m_mapMgr.end())
	{
		return iter->second->GetPlayerList();
	}
	return std::vector<uint64_t>();
}


//向指定位面添加怪物
void CPlaneMgr::AddCreature(uint64_t planeID, std::vector<uint64_t> & vCid)
{
	std::map<uint64_t, CPlane*>::iterator iter = m_mapMgr.find(planeID);
	if (iter != m_mapMgr.end())
	{
		iter->second->AddInPlane(vCid);
	}
}
void CPlaneMgr::AddCreature(uint64_t planeID, CharIDType cid)
{
	std::vector<uint64_t> vCid;
	vCid.push_back(cid);
	AddCreature(planeID, vCid);
}

void CPlaneMgr::AddCreature(uint64_t planeID, std::vector<uint32_t> & vNpcConfigid)
{
	std::vector<uint64_t> vCid;
	for (int i = 0; i < (int)vNpcConfigid.size();++i)
	{
		Npc * pNpc = g_GetCreatureMgr()->GetNpc(vNpcConfigid[i]);
		if (pNpc)
		{
			vCid.push_back(pNpc->GetCid());
		}
	}

	AddCreature(planeID, vCid);
}


bool CPlaneMgr::IsInPlane(uint64_t planeID, CharIDType cid)
{
	std::map<uint64_t, CPlane*>::iterator iter = m_mapMgr.find(planeID);
	if (iter != m_mapMgr.end())
	{
		return iter->second->IsInPlane(cid);
	}
	return false;
}

CPlane * CPlaneMgr::GetPlane(uint64_t planeID)
{
	std::map<uint64_t, CPlane*>::iterator iter = m_mapMgr.find(planeID);
	if (iter != m_mapMgr.end())
	{
		return iter->second;
	}
	return NULL;
}

void CPlaneMgr::RemoveCreature(uint64_t planeID, std::vector<uint64_t> & vCid)
{
	std::map<uint64_t, CPlane*>::iterator iter = m_mapMgr.find(planeID);
	if (iter != m_mapMgr.end())
	{
		iter->second->RemoveInPlane(vCid);
	}
}
void CPlaneMgr::RemoveCreature(uint64_t planeID, CharIDType cid)
{
	std::vector<uint64_t> vCid;
	vCid.push_back(cid);
	std::map<uint64_t, CPlane*>::iterator iter = m_mapMgr.find(planeID);
	if (iter != m_mapMgr.end())
	{
		iter->second->RemoveInPlane(vCid);
	}
}
void CPlaneMgr::RemoveCreature(uint64_t planeID, std::vector<uint32_t> & vNpcConfigid)
{
	std::vector<uint64_t> vCid;
	for (int i = 0; i < (int)vNpcConfigid.size(); ++i)
	{
		Npc * pNpc = g_GetCreatureMgr()->GetNpc(vNpcConfigid[i]);
		if (pNpc)
		{
			vCid.push_back(pNpc->GetCid());
		}
	}

	RemoveCreature(planeID, vCid);
}

uint32_t CPlaneMgr::GetPlaneConfigId(uint64_t planeID)
{
	std::map<uint64_t, CPlane*>::iterator iter = m_mapMgr.find(planeID);
	if (iter != m_mapMgr.end())
	{
		iter->second->GetPlaneConfigID();
	}

	return 0;
}

void CPlaneMgr::onClientMessage(uint32_t actionId, RECV_PACKAGE &package, uint64_t Id)
{
	switch (actionId)
	{
	case CLIENT_TO_LOGIC_PLANE_OPEN:
		OnHandleOpenPlane(package);
		break;
	case CLIENT_TO_LOGIC_PLANE_CLOSE:
		OnHandleClosePlane(package);
		break;
	default:
		break;
	}
}

void CPlaneMgr::OnHandleOpenPlane(RECV_PACKAGE &package)
{
	OpenPlaneReq gm;
	OpenPlaneRsp resultMsg;
	if (!gm.ParseFromArray(package.dataAfterHead, package.sizeAfterHead))
		return;
	if (gm.planeconfigid()<=0)
	{
		LeavePlane(gm.playerid());
		resultMsg.set_retcode(RET_SUCCESS);
		resultMsg.set_planeid(0);
	}
	else
	{
		int64_t planid = CreatePlane(gm.playerid(), gm.planeconfigid());
		if (planid > 0)
		{
			resultMsg.set_retcode(RET_SUCCESS);
		}
		else
		{
			resultMsg.set_retcode(RET_FAIL);
		}
		resultMsg.set_planeid(gm.planeconfigid());
	}

	g_GetLogicService()->SendDataToClient(gm.playerid(), EMODULE_ID_PLANE, LOGIC_TO_CLIENT_PLANE_OPEN_RESUTL,&resultMsg);

}
void CPlaneMgr::OnHandleClosePlane(RECV_PACKAGE &package)
{
	ClosePlaneReq gm;
	ClosePlaneRsp resultMsg;
	if (!gm.ParseFromArray(package.dataAfterHead, package.sizeAfterHead))
		return;
	LeavePlane(gm.playerid());
	resultMsg.set_retcode(RET_SUCCESS);
	g_GetLogicService()->SendDataToClient(gm.playerid(), EMODULE_ID_PLANE, LOGIC_To_CLIENT_PLANE_CLOSE_RESULT, &resultMsg);
}

bool CPlaneMgr::LeavePlane(uint64_t cid)
{
	bool result = true;
	Creature * pCreature = g_GetCreatureMgr()->GetCreature(cid);
	if (pCreature)
	{
		uint64_t planeID = pCreature->GetPlaneID();
		pCreature->SetPlaneID(0);

		std::map<uint64_t, CPlane*>::iterator iter = m_mapMgr.find(planeID);
		if (iter != m_mapMgr.end())
		{
			result= iter->second->LeavePlane(cid);
			if (result)
			{

				//先发离开事件
				//抛出事件
				PlaneLeaveEvent leavePlaneEvent;
				leavePlaneEvent.createCid = cid;
				leavePlaneEvent.planeConfigID = iter->second->GetPlaneConfigID();
				leavePlaneEvent.planeID = planeID;
				g_GetEvent()->FireExecute(EVENT_PLANE_LEAVE, cid, CREATURE_PLAYER, (PlaneLeaveEvent*)&leavePlaneEvent, sizeof(PlaneLeaveEvent));

				std::vector<uint64_t>  vTmp=iter->second->GetPlayerList();
				if (vTmp.empty())
				{
					DestroyPlane(cid,planeID);
				}

				//发送消息,给客户端用于显示提示动画
				ClosePlaneRsp rsp;
				rsp.set_retcode(RET_SUCCESS);
				rsp.set_planeid(0);
				g_GetLogicService()->SendDataToClient(cid, EMODULE_ID_SCENE, LOGIC_To_CLIENT_PLANE_CLOSE_RESULT, &rsp);

				
				pCreature->UpdateSeeLst();
				
			}
		}
	}

	return result;
}